using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class playerController : MonoBehaviour
{
    private NavMeshAgent agent;
    private Animator anim;

    private CharacterStats playerStat;

    private GameObject attackTarget;

    private float lastAttackTime;


    private bool isDead;

    private float stopDistance;

    void Awake()
    {
        agent = GetComponent<NavMeshAgent>();
        anim = GetComponent<Animator>();
        // 获取里面的角色信息和攻击信息
        playerStat = GetComponent<CharacterStats>();
        stopDistance = agent.stoppingDistance;
    }
    void OnEnable()
    {
        MouseManager.Instance.OnMouseClicked += MoveToTarget;
        MouseManager.Instance.OnEnemyClicked += EventAttack;

        GameManager.Instance.RegisterPlayer(playerStat);
    }
    void OnDisable()
    {
        if (MouseManager.IsInitialized)
        {
            MouseManager.Instance.OnMouseClicked -= MoveToTarget;
            MouseManager.Instance.OnEnemyClicked -= EventAttack;
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        // 加载玩家数据
        SaveManager.Instance.LoadPlayerData();
    }

    // Update is called once per frame
    void Update()
    {
        isDead = playerStat.CurrentHealth <= 0;
        if (isDead)
        {
            GameManager.Instance.NotifyObservers();
        }
        if (lastAttackTime > 0)
        {
            lastAttackTime -= Time.deltaTime;
        }
        SwitchAnimation();
    }
    void MoveToTarget(Vector3 target)
    {
        // 打断攻击协程
        StopAllCoroutines();
        if (isDead)
        {
            return;
        }
        agent.stoppingDistance = stopDistance;
        agent.isStopped = false;
        agent.destination = target;
    }

    void EventAttack(GameObject attackTarget)
    {
        if (isDead)
        {
            return;
        }
        if (attackTarget != null)
        {
            this.attackTarget = attackTarget;
            playerStat.isCritical = Random.value <= playerStat.attackData.criticalRate;
            StartCoroutine(MoveToAttackTarget());
        }
    }
    IEnumerator MoveToAttackTarget()
    {
        agent.isStopped = false;
        // 根据攻击范围确定 agent 停止范围
        agent.stoppingDistance = playerStat.attackData.attackRange;
        // 转向目标
        transform.LookAt(attackTarget.transform);
        // 攻击距离判断
        while ((attackTarget != null) && (Vector3.Distance(attackTarget.transform.position, transform.position) > (playerStat.attackData.attackRange)))
        {
            agent.destination = attackTarget.transform.position;
            yield return null;
        }
        // 停止移动并攻击
        agent.isStopped = true;
        if (lastAttackTime <= 0)
        {
            anim.SetBool("Critical", playerStat.isCritical);
            anim.SetTrigger("Attack");

            // 暴击效果
            if (playerStat.isCritical)
            {

                yield return new WaitForSeconds(0.3f);

            }

            lastAttackTime = playerStat.attackData.coldDown;
        }
        yield break;
    }
    void SwitchAnimation()
    {
        anim.SetFloat("Speed", agent.velocity.sqrMagnitude);
        anim.SetBool("Death", isDead);
    }
    // Animation Event
    void Hit()
    {
        if (attackTarget != null && attackTarget.CompareTag("Attackable"))
        {
            var rock = attackTarget.GetComponent<Rock>();
            if (rock != null)
            {
                if (rock.rockState == Rock.RockStates.HitNothing)
                {
                    rock.rockState = Rock.RockStates.HitEnemy;
                    var rb = attackTarget.GetComponent<Rigidbody>();
                    rb.velocity = Vector3.one;
                    rb.AddForce(transform.forward * 20, ForceMode.Impulse);
                }
            }
        }
        else if (attackTarget != null && transform.IsFacingTarget(attackTarget.transform))
        {
            var targetStat = attackTarget.GetComponent<CharacterStats>();

            targetStat.TakeDamage(playerStat, targetStat);
        }
    }
}
